import { edit_callLog, get_call_Token, socket_call } from "@/services/sickbeds";
import { useEffect, useRef, useState } from "react";
import './index.less';
import { Button, Modal, message } from "antd";
import AgoraRTC from 'agora-rtc-sdk-ng';
import AgoraRTM from 'agora-rtm-sdk';
import dayjs from 'dayjs';
import moment from 'moment';
import { endRecording, startRecording } from "@/services/broadcast";
import { random_int } from "@/utils/randomstring";
import AddRecord from "../EstablishedSickbeds/components/AddRecord";

var RTCclient: any;
var RTMclient: any;
var RTMchannel: any;
var my_uuid = '';
var to_uuid = '';
var channel = '';
var rtcToken = '';
var rtmToken = '';
//呼叫记录id
var chatlog_id: number;
var sid = '';
var resourceId = '';
// 录制随机uid
var record_uuid = random_int(7).toString();
var start_time = '';
// 用来放置本地音频轨道对象
var localAudioTrack: any;
var localVideoTrack: any;
const options = {
    appId: '268a993cd77249cf9f3c1e09a279e96c',
};
const videoConfig: any = {
    // 预设分辨率 默认 480p_1
    encoderConfig: '720p_1',
};
const Video = () => {
    // 获取URL参数
    const getUrlParam = (name: string) => {
        const reg = new RegExp(`(^|&)${name}=([^&]*)(&|$)`);
        const r = window.location.search.substring(1).match(reg);
        if (r != null) {
            return decodeURIComponent(r[2]);
        }
        return null;
    };
    // 存储当前病床编号
    const code: any = getUrlParam('code');
    // 存储添加记录模态框的状态
    const [isAddRecordModalOpen, setIsAddRecordModalOpen] = useState(false)

    // 倒计时秒 和 定时器
    const [times, settimes] = useState<any>(60);
    const timer: any = useRef();
    // 通话计时 和 计时器
    const [second, setsecond] = useState(0);
    const timemeter: any = useRef();
    const chatlog_second = useRef(second);
    chatlog_second.current = second;
    // 接听状态 用来处理 true显示拨打中倒计时/false显示已接通
    const [LocalInvitation, setLocalInvitation] = useState(true);
    // 取消呼叫loading状态
    const [cancelloading, setcancelloading] = useState(false);
    // 重新拨打loading状态
    const [callloading, setcallloading] = useState(false);
    // 通话状态 0未开始 1呼叫中 2通话中
    const [callstatus, setcallstatus] = useState(0);
    const call = useRef(callstatus);
    call.current = callstatus;

    //   页面初始化
    useEffect(() => {
        socketCall(2);
    }, []);

    // 监听页面刷新或关闭
    useEffect(() => {
        window.addEventListener('beforeunload', leave_Live_error);
        return () => {
            window.removeEventListener('beforeunload', leave_Live_error);
        };
    }, []);

    // 开始通话
    const start_video = async () => {
        if (code) {
            let request_body = {
                code,
            }
            let res: any = await get_call_Token(request_body);
            console.log('视频通话token', res);
            if (res.code == 200) {
                channel = res.data.channel;
                my_uuid = res.data.uuid;
                to_uuid = res.data.to_uuid;
                rtcToken = res.data.rtctoken;
                rtmToken = res.data.rtmtoken;
                RTCclient = AgoraRTC.createClient({ mode: 'live', codec: 'vp8' });
                RTCclient.setClientRole('host');
                //   监听用户推流
                RTCclient.on('user-published', async (user: any, mediaType: any) => {
                    await RTCclient.subscribe(user, mediaType);
                    console.log('user-published', user, mediaType);
                    if (mediaType == 'video') {
                        // 订阅完成后，从 `user` 中获取远端视频轨道对象
                        const remoteVideoTrack = user.videoTrack;
                        // 订阅完成，播放远端音视频
                        // 传入 DIV 节点，让 SDK 在这个节点下创建相应的播放器播放远端视频
                        remoteVideoTrack.play(document.getElementById('audience'), {
                            mirror: false,
                            fit: 'contain',
                        });
                    }
                    if (mediaType == 'audio') {
                        // 订阅完成后，从 `user` 中获取远端音频轨道对象
                        const remoteAudioTrack = user.audioTrack;
                        // 播放音频因为不会有画面，不需要提供 DOM 元素的信息
                        remoteAudioTrack.play();
                    }
                });
                //   监听用户取消推流
                RTCclient.on('user-unpublished', async (user: any, mediaType: any) => {
                    console.log('user-unpublished', user, mediaType);
                    // 远端用户取消发布或离开频道
                });
                RTCclient.join(options.appId, res.data.channel, res.data.rtctoken, res.data.uuid).then(
                    async () => {
                        localAudioTrack = await AgoraRTC.createMicrophoneAudioTrack();
                        localVideoTrack = await AgoraRTC.createCameraVideoTrack(videoConfig);
                        await RTCclient.publish([localAudioTrack, localVideoTrack]);
                        localVideoTrack.play(document.getElementById('host'), {
                            mirror: false,
                            fit: 'contain',
                        });
                    },
                );
                // 加入频道
                join(res.data.uuid, res.data.rtmtoken, res.data.channel, res.data.to_uuid);
            } else {
                message.error(res.msg);
            }
        }
    }

    // 加入RTM频道
    const join = async (uuid: number, rtmtoken: string, channel: string, to_uuid: number) => {
        console.log('to_uuid123456789', to_uuid);

        RTMclient = AgoraRTM.createInstance(options.appId);
        await RTMclient.login({ uid: uuid.toString(), token: rtmtoken });
        RTMchannel = RTMclient.createChannel(channel);
        await RTMchannel.join();
        // 点对点消息，用来处理连麦生命周期 ， 接收挂断通知
        RTMclient.on('MessageFromPeer', async (message_n: any, peerId: number) => {
            console.log('message ', message_n, ' peerId', peerId);
            // 对方接受呼叫邀请
            if (
                message_n.messageType === 'TEXT' &&
                JSON.parse(message_n.text).type == 'video_LocalInvitationAccepted' &&
                peerId == to_uuid
            ) {
                // 清除定时器
                clearInterval(timer.current);
                // 开始通话倒计时
                start_second();
                // 接听状态改为已接听
                setLocalInvitation(false);
                //修改呼叫状态为呼叫中
                setcallstatus(1);
                // 修改呼叫记录（通话中）
                editCallLog(1);
                // 开始录制
                start_recording(channel);
                //修改通话状态(2通话中)
                setcallstatus(2);
                message.warning('对方已接受呼叫邀请');
            }
            // 对方已拒绝呼叫邀请
            if (
                message_n.messageType === 'TEXT' &&
                JSON.parse(message_n.text).type == 'video_LocalInvitationRefused' &&
                peerId == to_uuid
            ) {
                console.log('message ' + message_n.text + ' peerId' + peerId);
                // 修改取消呼叫loading状态
                setcancelloading(true);
                // 取消推流
                leave_Live('', 'reject');
                // 修改呼叫记录（已拒绝）
                editCallLog(2);
                //修改通话状态 (0未开始)
                setcallstatus(0);
                message.warning('对方已拒绝呼叫邀请');
            }
            // 对方取消视频通话
            if (
                message_n.messageType === 'TEXT' &&
                JSON.parse(message_n.text).type == 'end_video_fNFMEI1B' &&
                peerId == to_uuid
            ) {
                console.log('message ' + message_n.text + ' peerId' + peerId);
                // 修改取消呼叫loading状态
                setcancelloading(true);
                // 取消推流
                await leave_Live('end', 'reject');
                setsecond(0);
                //通话状态 0未开始
                setcallstatus(0);
                message.warning('对方已取消通话');
            }
        });
    };

    //   长链接呼叫
    const socketCall = async (type: number) => {
        // 接通倒计时
        start_times();
        let request_body = {
            code,
            type,
        }
        let res: any = await socket_call(request_body);
        console.log('长链接呼叫', res);
        if (res.code == 200) {
            // 存储当前呼叫记录id
            chatlog_id = res.data.id;
            //修改呼叫状态为呼叫中
            setcallstatus(1);
            // 开始通话
            start_video();
            // 视频录制弹窗提醒
            Modal.warning({
                title: '温馨提示：',
                content: '为了维护您的合法权益，平台将自动录制视频的全过程',
                closable: true,
                centered: true,
            });
        } else {
            message.error(res.msg);
            setTimeout(() => {
                window.close();
            }, 500)
        }
        setcallloading(false);
    }
    const error_edit_chatlog = async (status: number) => {
        let request_body = {
            id: chatlog_id,
            status: status,
            time: chatlog_second.current,
        };
        await edit_callLog(request_body);
    };
    //关闭页面 异常退出挂断
    const leave_Live_error = () => {
        if (call.current == 1) {
            error_edit_chatlog(4);
        }
        if (call.current == 2) {
            error_edit_chatlog(3);
            // 结束录制
            end_recording();
        }
        RTMclient.sendMessageToPeer(
            { text: JSON.stringify({ type: 'end_video_fNFMEI1B' }) },
            to_uuid.toString(),
        );

        window.opener.postMessage('refreshCallList', '*');

        RTCclient = null;
    };
    // 正常挂断
    const leave_Live = async (type?: any, status?: any) => {
        //退出RTC RTM 关闭页面
        if (status != 'reject') {
            RTMclient.sendMessageToPeer(
                { text: JSON.stringify({ type: 'end_video_fNFMEI1B' }) },
                to_uuid.toString(),
            );
        }
        if (type == 'end') {
            editCallLog(3);
            // 结束录制
            end_recording();
            // 显示添加记录模态框
            isShowAddRecord(true)
        }
        if (type == 'quit') {
            editCallLog(4);
        }
        window.opener.postMessage('refreshCallList', '*');
        // 清除定时器
        clearInterval(timer.current);
        // 重置
        settimes(60);
        // 接听状态 显示拨打中倒计时
        setLocalInvitation(true);

        // 清除延时器
        clearInterval(timemeter.current);

        RTMclient.logout();
        if (localAudioTrack) {
            localAudioTrack.close();
        }
        if (localVideoTrack) {
            localVideoTrack.close();
        }
        if (RTCclient) {
            await RTCclient.unpublish();
        }
        // 离开频道。
        await RTCclient.leave();
        RTCclient = null;
        //修改呼叫状态为未开始
        setcallstatus(0);
        setcancelloading(false);
    };

    //修改当前呼叫状态
    const editCallLog = async (status: number) => {
        console.log('通话时长', chatlog_second.current, second);
        let request_body = {
            id: chatlog_id,
            status: status,
            time: chatlog_second.current,
        };
        let params = await edit_callLog(request_body);
        console.log(params);
    };

    // 开始录制按钮回调
    const start_recording = async (channel: string) => {
        if (chatlog_id) {
            let request_body = {
                id: chatlog_id,
                cname: channel,
                uid: record_uuid,
                type: 3,
                fileNamePrefix: process.env.UMI_ENV,
                mixedVideoLayout: 1,
            };
            let params: any = await startRecording(request_body);
            console.log('开始录制', params);
            if (params.msg == 'ok') {
                sid = params.data.sid;
                resourceId = params.data.resourceId;
                start_time = moment().format('YYYY-MM-DD HH:mm:ss');
            }
        }
    };

    // 结束录制按钮回调
    const end_recording = async () => {
        let request_body = {
            cname: channel,
            uid: record_uuid,
            resourceId,
            sid,
            start_time,
            end_time: moment().format('YYYY-MM-DD HH:mm:ss'),
        };
        let params: any = await endRecording(request_body);
        console.log('结束录制', params);
    };
    //接通倒计时
    const start_times = () => {
        console.log('接通倒计时');
        clearInterval(timer.current);
        timer.current = setInterval(() => {
            settimes((times: number) => {
                if (times > 0) {
                    return times - 1;
                } else if (times == 0) {
                    leave_Live();
                    setcallstatus(0);
                    return 60;
                }
            });
        }, 1000);
    };
    //通话计时
    const start_second = () => {
        console.log('开始通话计时');
        clearInterval(timemeter.current);
        timemeter.current = setInterval(() => {
            setsecond((second) => {
                return second + 1;
            });
        }, 1000);
    };
    //计时器格式化
    const studyTime = (t: number) => {
        let hour: any = Math.floor(t / 60 / 60);
        let minute: any = Math.floor((t / 60) % 60);
        let second: any = Math.floor(t % 60);
        if (hour < 10) {
            hour = '0' + hour;
        }
        if (minute < 10) {
            minute = '0' + minute;
        }
        if (second < 10) {
            second = '0' + second;
        }
        return hour + ':' + minute + ':' + second;
    };

    // 控制添加记录模态框的显示与隐藏
    const isShowAddRecord = (status: boolean) => {
        setIsAddRecordModalOpen(status)
    }
    return (
        <div className="box">
            <div
                className="call_box_video"
                id="call_box_video"
            >
                <div id="left_box">
                    <div id="host"></div>
                    <div id="audience"></div>
                    {LocalInvitation ? (
                        callstatus == 1 ? (
                            <div className="call_text">
                                <p style={{ marginTop: '40%', color: '#929292' }}>等待对方接听······</p>
                                {times <= 55 ? (
                                    <Button
                                        type="primary"
                                        danger
                                        onClick={() => {
                                            setcancelloading(true);
                                            leave_Live('quit');
                                        }}
                                        loading={cancelloading}
                                    >
                                        取消呼叫
                                    </Button>
                                ) : (
                                    <></>
                                )}
                                <p style={{ marginTop: '40px', color: '#929292' }}>{times < 0 ? 0 : times} s</p>
                            </div>
                        ) : (
                            <div className="call_text">
                                <p style={{ marginTop: '40%', color: '#929292' }}>已取消通话</p>

                                <Button
                                    type="primary"
                                    danger
                                    onClick={() => {
                                        setcallloading(true);
                                        // start_video();
                                        socketCall(2);
                                    }}
                                    loading={callloading}
                                >
                                    重新拨打
                                </Button>
                            </div>
                        )
                    ) : (
                        <div className="callend_text">
                            <p style={{ marginTop: '50%', color: '#fff' }}>通话中 {studyTime(second)}</p>
                            <Button
                                type="primary"
                                danger
                                onClick={async () => {
                                    await leave_Live('end');
                                    setsecond(0);
                                }}
                            >
                                挂断
                            </Button>
                        </div>
                    )}
                </div>
            </div>
            {/* 添加记录模态框 */}
            {isAddRecordModalOpen ? <AddRecord isAddRecordModalOpen={isAddRecordModalOpen} isShowAddRecord={isShowAddRecord} id={chatlog_id}></AddRecord> : <></>}
        </div>

    )
}
export default Video;